using System;
using System.Collections;
using System.Data;
using System.Xml;
using LocalBoard.Domain;

namespace LocalBoard.Persistence.MockAccessor
{
	/// <summary>
	/// Summary description for MockClubAccessor.
	/// </summary>
	public class MockClubAccessor : IClubAccessor, IMockAccessor
	{
		private int _oId = 0;
		private DataTable _clubTable = new DataTable("Board");
		private MockAccessorFactory _accessorFactory;
		private IClubRoleAccessor _clubRoleAccessor;

		public static readonly MockClubAccessor Instance = new MockClubAccessor();

		private MockClubAccessor()
		{
			_clubTable.Columns.Add("Id", typeof(int));
			_clubTable.Columns.Add("UniqueName", typeof(string));
			_clubTable.Columns.Add("Name", typeof(string));
			_clubTable.Columns.Add("Category_Id", typeof(int));
			_clubTable.Columns.Add("Description", typeof(string));
			_clubTable.Columns.Add("ClubType", typeof(string));
			_clubTable.Columns.Add("Information", typeof(string));

			Initialize();
			_accessorFactory = new MockAccessorFactory();
			_clubRoleAccessor = _accessorFactory.GetClubRoleAccessor();
		}

		private void Initialize()
		{
			_oId = 0;
			Insert(new Club("LocalBoard", "Club Station", 1, "", "", null));
			Insert(new Club("Weblog", "General Weblog", 1, "", "", null));
		}

		public void ResetDataTable()
		{
			_clubTable.Clear();
			Initialize();
		}

		public void RemoveRows(int tableIndex, DataRow[] rows)
		{
			foreach(DataRow row in rows)
				_clubTable.Rows.Remove(row);
		}

		public DataRow[] ExecuteFilter(string filterExpression)
		{
			return _clubTable.Select(filterExpression);
		}

		#region IClubAccessor Members

		public ArrayList GetClubList()
		{
			ArrayList clubList = new ArrayList();
			foreach(DataRow row in _clubTable.Rows)
			{
				clubList.Add(GetClubFromResultRow(row));
			}
			return clubList;
		}

		public Club Get(int id)
		{
			DataRow[] result = _clubTable.Select(string.Format("Id={0}", id));
			if(result.Length > 0)
				return GetClubFromResultRow(result[0]);
			else
				return null;
		}

		public int Insert(Club club)
		{
			_oId++;
			DataRow newRow = _clubTable.NewRow();
			newRow["Id"] = _oId;
			FillDataRowFromClub(ref newRow, club);
			_clubTable.Rows.Add(newRow);
			_clubTable.AcceptChanges();

			return _oId;
		}

		public void Update(Club club)
		{
			DataRow row = FindClubDataRow(club.Id);
			if(row!=null)
			{
				FillDataRowFromClub(ref row, club);
				_clubTable.AcceptChanges();
			}
		}

		private void FillDataRowFromClub(ref DataRow row, Club club)
		{
			row["UniqueName"] = club.UniqueName;
			row["Name"] = club.Name;
			row["Description"] = club.Description;
			row["ClubType"] = club.ClubType.ToString();
			row["Information"] = club.Information != null ? club.Information.OuterXml : "";
		}

		public void Delete(int id)
		{
			DataRow row = FindClubDataRow(id);
			if(row!=null)
			{
				_clubTable.Rows.Remove(row);
				_clubTable.AcceptChanges();
			}
		}

		public void AssignManagerToClub(int profileId, int id)
		{
			UserRole clubManagerRole = _clubRoleAccessor.Get(UserRole.CLUB_MANAGER_ROLE_NAME, id);
			if(clubManagerRole == null)
				clubManagerRole = _clubRoleAccessor.Get(_clubRoleAccessor.Insert(UserRole.CLUB_MANAGER_ROLE_NAME, id), id);
			_clubRoleAccessor.AddClubRoleToProfile(clubManagerRole.Id, profileId, id);
		}

		public ArrayList GetClubListByKeyword(string keyword)
		{
			throw new NotImplementedException();
		}
		#endregion

		private DataRow FindClubDataRow(int id)
		{
			foreach(DataRow row in _clubTable.Rows)
			{
				if(DataConverter.GetInteger(row["Id"])==id)
					return row;
			}
			return null;
		}

		private Club GetClubFromResultRow(DataRow row)
		{
			return new Club(DataConverter.GetInteger(row["Id"]), DataConverter.GetString(row["UniqueName"]), DataConverter.GetString(row["Name"]), DataConverter.GetInteger(row["Category_Id"]), DataConverter.GetString(row["Description"]), DataConverter.GetString(row["ClubType"]), GetXmlNodeFromXmlString(DataConverter.GetString(row["Information"])));
		}

		private XmlNode GetXmlNodeFromXmlString(string xmlString)
		{
			if(xmlString == null || xmlString.Length == 0)
				return null;
			XmlDocument doc = new XmlDocument();
			doc.LoadXml(xmlString);
			return doc;
		}

	}
}
